﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../global/head.h"
#include "../macro/head.h"
#include "aio_epoll_notify.h"
#include "aio_helper.h"
#include "aio_thread.h"
#include "aio_impl.h"

/////////////////////////////////////////////////////////////////////////////////////////
// 
namespace xos_aio
{
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    static aio_impl::POOL * pool_ptr = 0;

    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    aio_impl::aio_impl()
    {
        m_pEpollNotify = 0;
        m_pCallback = 0;
        m_pAioThread = 0;
        m_hKqueue = -1;
    }

    aio_impl::~aio_impl()
    {
        term();
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int aio_impl::get_addr( POOL *** pppPool, LIST *** pppList )
    {
        int ret = 0;
        if( pppPool )
        {
            *pppPool = &pool_ptr;
        }
        if( pppList )
        {
            *pppList = 0;
        }
        return ret;
    }

    int aio_impl::notify( xos_box::i_msg *& p )
    {
        int nRet = 0;
        p->set_runnable( 0, m_pCallback );
        g_pSysData->m_pCallbackObj->notify( p );
        return nRet;
    }

    int aio_impl::init()
    {
        using namespace std;
        int nRet = 0;
      
        if( 0 == nRet )
        {
            m_hKqueue = kqueue();
            if( -1 == m_hKqueue )
            {
                nRet = 1;
            }
        }

        if( 0 == nRet )
        {
            m_pAioThread = new aio_thread( this );
            m_pAioThread->init();
        }

        if( 0 == nRet )
        {
            m_pEpollNotify = new aio_epoll_notify( this );
            nRet = m_pEpollNotify->init();
        }

        return nRet;
    }

    int aio_impl::term()
    {
        int nRet = 0;

        if( m_pAioThread )
        {
            m_pAioThread->term();
            delete m_pAioThread;
            m_pAioThread = 0;
        }

        if( m_pEpollNotify )
        {
            m_pEpollNotify->term();
            delete m_pEpollNotify;
            m_pEpollNotify = 0;
        }

        if( -1 != m_hKqueue )
        {
            close( m_hKqueue );
            m_hKqueue = -1;
        }

        m_request_list.put_back_to_pool( true );
        m_return_list.put_back_to_pool( true );
        m_pCallback = 0;

        return nRet;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    // 
    // set callback. 
    // 
    int aio_impl::set_callback( xos::f_runnable pCallback )
    {
        int ret = 0;
        m_pCallback = pCallback;
        return ret;
    }

    // 
    // aio request
    // 
    // m_nData[0] : enumAioType
    // 
    int aio_impl::post_request( xos_box::i_msg *& pMsg )
    {
        int nRet = 0;
        m_pEpollNotify->notify( pMsg );
        return nRet;
    }

} // xos_aio
